/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.lucava.boatskeeper.client.presenter.user;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HasValue;
import com.google.gwt.user.client.ui.ListBox;
import java.util.List;
import net.customware.gwt.dispatch.client.DispatchAsync;
import net.customware.gwt.presenter.client.EventBus;
import net.customware.gwt.presenter.client.place.Place;
import net.customware.gwt.presenter.client.place.PlaceRequest;
import net.customware.gwt.presenter.client.widget.WidgetDisplay;
import org.lucava.boatskeeper.client.PlaceMapper;
import org.lucava.boatskeeper.client.event.EditCancelledEvent;
import org.lucava.boatskeeper.client.event.UpdatedEvent;
import org.lucava.boatskeeper.client.presenter.ViewPresenter;
import org.lucava.boatskeeper.shared.Role;
import org.lucava.boatskeeper.shared.User;
import org.lucava.boatskeeper.shared.rpc.role.GetRoles;
import org.lucava.boatskeeper.shared.rpc.role.GetRolesResult;
import org.lucava.boatskeeper.shared.rpc.user.AddUser;
import org.lucava.boatskeeper.shared.rpc.user.AddUserResult;
import org.lucava.boatskeeper.shared.rpc.user.GetUser;
import org.lucava.boatskeeper.shared.rpc.user.GetUserResult;
import org.lucava.boatskeeper.shared.rpc.user.SaveUser;
import org.lucava.boatskeeper.shared.rpc.user.SaveUserResult;

/**
 *
 * @author glenn
 */
public class EditUserPresenter extends ViewPresenter<EditUserPresenter.Display> {

    public interface Display extends WidgetDisplay {

        HasClickHandlers getSaveButton();

        HasClickHandlers getCancelButton();

        public HasValue<String> getLogin();

        public HasValue<String> getPassword();

        public ListBox getRoleList();
    }
    public static Place PLACE;
    private User user;
    private List<Role> roles;

    public EditUserPresenter(DispatchAsync dispatcher, EventBus eventBus, Display display) {
        super(dispatcher, eventBus, display);
        bind();
    }

    @Override
    protected void onBind() {
        display.getSaveButton().addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                doSave();
            }
        });

        display.getCancelButton().addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                user = null;
                eventBus.fireEvent(new EditCancelledEvent(PlaceMapper.LIST_USER));
            }
        });
    }

    protected void doSave() {
        if (user == null) {
            user = new User();
        }

        user.setLogin(display.getLogin().getValue());
        user.setPassword(display.getPassword().getValue());

        if (user.getId() != null) {
            getDispatcher().execute(new SaveUser(user), new AsyncCallback<SaveUserResult>() {
                @Override
                public void onSuccess(SaveUserResult result) {
                    eventBus.fireEvent(new UpdatedEvent(PlaceMapper.LIST_USER, result.getData()));
                }

                @Override
                public void onFailure(Throwable caught) {
                    Window.alert("Error updating boat");
                }
            });
        } else {
            getDispatcher().execute(new AddUser(user), new AsyncCallback<AddUserResult>() {
                @Override
                public void onSuccess(AddUserResult result) {
                    eventBus.fireEvent(new UpdatedEvent(PlaceMapper.LIST_USER, result.getData()));
                }

                @Override
                public void onFailure(Throwable caught) {
                    caught.printStackTrace();
                    Window.alert("Error Adding boat");
                }
            });
        }
        user = null;
    }

    private void getUser(Integer id) {
        getDispatcher().execute(new GetUser(id), new AsyncCallback<GetUserResult>() {
            @Override
            public void onSuccess(GetUserResult result) {
                user = result.getData();
                refreshDisplay();

            }

            @Override
            public void onFailure(Throwable caught) {
                // TODO Auto-generated method stub
            }
        });

    }

    private void fetchRoles() {
        getDispatcher().execute(new GetRoles(), new AsyncCallback<GetRolesResult>() {
            @Override
            public void onSuccess(GetRolesResult result) {
                roles = result.getList();
            }

            @Override
            public void onFailure(Throwable caught) {
                System.out.println(caught.getMessage());
                Window.alert(caught.getMessage());
            }
        });
    }

    @Override
    protected void onPlaceRequest(PlaceRequest request) {

        String userId = request.getParameter("id", null);
        fetchRoles();
        if (userId != null) {
            getUser(Integer.parseInt(userId));
        } else {
            refreshDisplay();
        }
    }

    @Override
    public void refreshDisplay() {
        if (user != null) {
            Integer selectedIndex = 0;
            display.getLogin().setValue(user.getLogin());
            for (Role role : roles) {
                display.getRoleList().addItem(role.getName(), role.getId().toString());
                if (role.getId().equals(user.getRoleId())) {
                    selectedIndex = display.getRoleList().getItemCount() - 1;
                }
            }
            display.getRoleList().setSelectedIndex(selectedIndex);



        } else {
            display.getLogin().setValue(null);
            display.getPassword().setValue(null);
            for (Role role : roles) {
                display.getRoleList().addItem(role.getName(), role.getId().toString());
            }
            display.getRoleList().setSelectedIndex(0);
        }



    }

    @Override
    public Place getPlace() {
        return PLACE;
    }
}
